package cn.itlaobing.framework;

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import io.github.lukehutch.fastclasspathscanner.FastClasspathScanner;

/**
 * Servlet implementation class LaobingServlet
 */

//拦截以.do结尾的请求
@WebServlet(value="*.do",loadOnStartup=1)
public class LaobingServlet extends HttpServlet {
	
	Log log=LogFactory.getLog(LaobingServlet.class);
	
	private static final long serialVersionUID = 1L;
  
    public LaobingServlet() {
        super();
      
    }

	public void init() throws ServletException {
		//扫描包下的所有的类
		FastClasspathScanner fcs=new FastClasspathScanner("cn.itlaobing.web.controller");
		List<String> packageClasses=fcs.scan().getNamesOfAllClasses();
		
		for (String packageClass : packageClasses) {
			proccessRquestMapping(packageClass);
		}
		
	}
	
	/**
	 * 将每个类中的映射保存到 application范围中
	 */
	private void proccessRquestMapping(String stringControllerClass){
		//取得类的Class
		try {
			Class clsController=Class.forName(stringControllerClass);
			//取得所有的定义的方法
			Method[] methods=clsController.getDeclaredMethods();
			for (Method method : methods) {
				proccessAnnotation(clsController,method);
			}
			
			
		} catch (Exception e) {
			log.error(e);
			throw new RuntimeException(e);
		}
		
		
		
	}
	
	public static final String ATTRREQUEST_MAPPING="ATTRREQUEST_MAPPING";
	
	private void proccessAnnotation(Class clsController,Method method) throws InstantiationException, IllegalAccessException{
		
		//实例化controller 
		Object controller=clsController.newInstance();
		
		RequestMapping requestMapping=method.getAnnotation(RequestMapping.class);
		if(requestMapping!=null && requestMapping.value()!=null && !"".equals(requestMapping.value())){
			log.info(">>>>>>>>>>>"+requestMapping.value());
			
			Handler handler=new Handler();//将 请求路径，请求路径对应的controller方法，controller实例对象保存到handler对象中
			handler.setPath(requestMapping.value());
			handler.setMethod(method);
			handler.setHandlerObject(controller);
			
			ServletContext application=this.getServletContext();
			Map<String,Handler> requestMappingMap=(Map<String,Handler>)application.getAttribute(ATTRREQUEST_MAPPING);
			if(requestMappingMap==null){
				requestMappingMap=new HashMap<>();
				application.setAttribute(ATTRREQUEST_MAPPING, requestMappingMap);
			}
			requestMappingMap.put(requestMapping.value(), handler);
		}
		
	}
	
	

	
	public void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//取得请求地址
		String requestPath=request.getServletPath();
		log.info(requestPath);
		
		//从application范围中取出请求映射
		ServletContext application=this.getServletContext();
		Map<String,Handler> requestMappingMap=(Map<String,Handler>)application.getAttribute(ATTRREQUEST_MAPPING);
		
		if(requestMappingMap!=null && requestMappingMap.containsKey(requestPath)){
			//执行方法
			Handler handler=requestMappingMap.get(requestPath);
			Method handlerMethod=handler.getMethod();
			Object controller=handler.getHandlerObject();
			
			try {
				String actionReturn=(String) handlerMethod.invoke(controller, request,response);
				if(actionReturn==null || "".equals(actionReturn)){
					return;
				}
				if(actionReturn.startsWith("redirect:")){
					
					response.sendRedirect(request.getContextPath()+actionReturn.replaceAll("redirect:",""));
					return;
				}else{
					request.getRequestDispatcher(actionReturn).forward(request, response);
					return;
				}
				
				
				
			} catch (Exception e) {
				log.error(e);
				throw new RuntimeException(e);
			}
		}
		
		
		
	}

}
